package com.ocom.webapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.constant.WebApiServiceUrl;
import com.ocom.common.constant.XFPayUrl;
import com.ocom.common.entity.card.EntityCardInfo;
import com.ocom.common.entity.card.EntityXfAccountInfo;
import com.ocom.common.entity.card.EntityXfAccountType;
import com.ocom.common.entity.company.EntityImportLog;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.payconfig.GzhRefundQueryRequest;
import com.ocom.common.request.payhandle.GzhMngHandleRequest;
import com.ocom.common.request.simple.RechargeRequest;
import com.ocom.common.request.web.CommonPidVo;
import com.ocom.common.request.web.WebDelCardVo;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.CommonUtil;
import com.ocom.common.utils.DateUtil;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.webapi.ImportCardVo;
import com.ocom.redis.util.RedisUtil;
import com.ocom.security.authentication.YoCiUser;
import com.ocom.security.utils.SecurityUtils;
import com.ocom.webapi.feign.*;
import com.ocom.webapi.service.ConsumeAccountService;
import com.ocom.webapi.vo.accounttypepage.DetailsVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.hutool.poi.excel.cell.CellUtil.getCellValue;


@Slf4j
@RestController
@PreAuthorize("@pms.hasRole('ROLE_WEB')" )
public class ConsumeAccountController {

    @Autowired
    private ConsumeAccountService consumeAccountService;

    @Autowired
    private PayConfigClientService payConfigClientService;

    @Autowired
    private PayHandleFeignService payHandleFeignService;

    @Autowired
    MqSimpleService mqSimpleService;

    @Autowired
    private MinioClientService minioClientService;

    @Autowired
    CompanyClientService companyClientService;


    @Resource
    RedisUtil redisUtil;



    /**
     * 获取账户信息列表（ConsumeAccount/onShow）
     * */
    @PostMapping(XFPayUrl.URL_ConsumeAccountOnShow)
    public Result ConsumeAccountOnShow(@Validated @RequestBody DetailsVo detailsVo){
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        detailsVo.setComId(yoCiUser.getComId());
        log.info("获取账户信息列表请求参数:{{}}",detailsVo);
        return consumeAccountService.ConsumeAccountDetails(detailsVo);
    }

    /**
     * 个人账户充值(ConsumeAccount/recharge)
     * */
    @PostMapping(XFPayUrl.URL_ConsumeAccountRecharge)
    public Result ConsumeAccountRecharge(@Validated @RequestBody Map<String,Object> map){
        log.info("个人账户充值请求参数:{{}}",map);
//        map.put("remark","111144");
        if(!SecurityUtils.getYoCiUser().getComId().equals(Long.valueOf(map.get("comId").toString()))){
            return ResultUtil.error(ResultEnum.Err_4100);
        }
        return consumeAccountService.ConsumeAccountRecharge(map);
    }

    /**
     * 批量充值
     * @param file
     * @return
     */
    @PostMapping(WebApiServiceUrl.URL_importRecharge)
    public Result RechargeImport(@RequestPart("file") MultipartFile file,@RequestParam(defaultValue = "0") Integer subAccount) {
        Long comId =SecurityUtils.getYoCiUser().getComId();

        Result result2 = minioClientService.upload(file);

        if(result2.getCode()==200){
            JSONObject jsonObject =JSON.parseObject(JSON.toJSONString( result2.getData()));

            EntityImportLog entityImportLog =new EntityImportLog();

            entityImportLog.setComId(comId);
            entityImportLog.setUrl(jsonObject.getString("imageUrl"));
            entityImportLog.setType(1);
            entityImportLog.setRemark("批量充值");

            companyClientService.importLog(entityImportLog);
        }


        Long timestamp = System.currentTimeMillis();
        //        1、用HSSFWorkbook打开或者创建“Excel文件对象”
        //        2、用HSSFWorkbook对象返回或者创建Sheet对象
        //        3、用Sheet对象返回行对象，用行对象得到Cell对象
        //        4、对Cell对象读写。
        //获得文件名
        Workbook workbook = null ;
        String fileName = file.getOriginalFilename();
        assert fileName != null;
        if(fileName.endsWith("xls")){
            //2003
            try {
                workbook = new HSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(fileName.endsWith("xlsx")){
            //2007
            try {
                workbook = new XSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            try {
                throw new Exception("文件不是Excel文件");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        assert workbook != null;
        Sheet sheet = workbook.getSheetAt(0);
        int rows = sheet.getLastRowNum();// 指的行数，一共有多少行+
        if(rows==0){
            try {
                throw new Exception("请填写数据");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Map<String,Object> map1=new HashMap<>();
        map1.put("key","ImportErr:detail:"+comId+":"+timestamp);
        map1.put("type",4);
        map1.put("name","批量充值");
        map1.put("timestamp",timestamp);
        map1.put("datetime", DateUtil.getDateTime());
        redisUtil.leftPush("ImportErr:"+comId,map1,86400l);

        int errCount = 0;
        BREAKOFF:
        for (int i = 1; i < rows+1; i++) {
            if(i>5005){
                break BREAKOFF;
            }

            // 读取左端单元格
            Row row = sheet.getRow(i);
            // 行不为空
            if (row != null) {
                try {
                    String errMsg = "";
                    // **读取cell**
                    RechargeRequest rechargeRequest=new RechargeRequest();
                    rechargeRequest.setSubAccount(subAccount);
                    rechargeRequest.setTimestamp(timestamp);
                    rechargeRequest.setComId(comId);

                    // 人员编号
                    String pCode = JSON.toJSONString(getCellValue(row.getCell(0))).replace("\"", "").replace("\\t", "");
                    if (!CommonUtil.isNull(pCode) && !pCode.equals("null")){
                        rechargeRequest.setPCode(pCode);
                        errCount =0 ;
                    }else{
                        errMsg += "编号为空,";
                        errCount++;
                        if(errCount>10){
                            break BREAKOFF;
                        }
                    }

                    // 人员卡号
                    String money = JSON.toJSONString(getCellValue(row.getCell(1))).replace("\"", "").replace("\\t", "");
                    if (!CommonUtil.isNull(money) && !money.equals("null") && !money.equals("0")){
                        BigDecimal bd=new BigDecimal(money);
                        BigDecimal bd2=bd.multiply(new BigDecimal(100));
                        rechargeRequest.setMoney(bd2.longValue());
                    }else{
                        errMsg += "金额为空,";
                    }

                    //调用mq
                    if(CommonUtil.isNull(errMsg)){
                        mqSimpleService.recharge(rechargeRequest);
                    }else{
                        Map<String,Object> map=new HashMap<>();
                        map.put("errMsg",errMsg);
                        map.put("json",rechargeRequest);
                        redisUtil.leftPush("ImportErr:detail:"+comId+":"+timestamp,map,86400l);
                    }
                }catch (Exception e){
                    log.error("导入异常 【{}】",e );
                }

            }
        }
        return ResultUtil.success();
    }


        /**
		 * 个人账户发卡（ConsumeAccount/issuing）
		 * */
    @PostMapping(XFPayUrl.URL_ConsumeAccountIssuing)
    public Result ConsumeAccountIssuing(@Validated @RequestBody Map<String,Object> map){
        log.info("个人账户发卡请求参数:{{}}",map);
        if(!SecurityUtils.getYoCiUser().getComId().equals(Long.valueOf(map.get("comId").toString()))){
            return ResultUtil.error(ResultEnum.Err_4100);
        }
        map.put("comId", SecurityUtils.getYoCiUser().getComId());
        return consumeAccountService.ConsumeAccountIssuing(map);
    }

    /**
     * 个人账户挂失/解挂（ConsumeAccount/cardLoss）
     * */
    @PostMapping(XFPayUrl.URL_ConsumeAccountCardLoss)
    public Result ConsumeAccountCardLoss(@Validated @RequestBody Map<String,Object> map){
        log.info("个人账户挂失/解挂请求参数:{{}}",map);
        return consumeAccountService.ConsumeAccountCardLoss(map);
    }

    /*
     * @Description:卡操作记录明细（CardOperDetail/onShow）
     * @Author: lu
     * @Date: 2022/6/24 9:03
     * @param jsonObject:
     * @return: com.ocom.common.resp.Result
     **/
    @PostMapping(XFPayUrl.URL_CardOperDetailOnShow)
    public Result cardOperDetailOnShow(@Validated @RequestBody JSONObject jsonObject){
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        jsonObject.put("comId", yoCiUser.getComId());
        if(23 == yoCiUser.getRole()){
            jsonObject.put("deptId",yoCiUser.getDeptId());
        }

        return payConfigClientService.cardOperDetailList(jsonObject);
    }

    /*
     * @Description:卡操作汇总（CardOperRecord/onShow）
     * @Author: lu 
     * @Date: 2022/6/24 9:03
     * @param jsonObject:  
     * @return: com.ocom.common.resp.Result
     **/
    @PostMapping(XFPayUrl.URL_cardOperRecordOnShow)
    public Result cardOperRecordOnShow(@Validated @RequestBody JSONObject jsonObject){
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        jsonObject.put("comId", yoCiUser.getComId());
        if(23 == yoCiUser.getRole()){
            jsonObject.put("deptId",yoCiUser.getDeptId());
        }
        return payConfigClientService.countCardOperRecord(jsonObject);
    }


    /**
     * zhuhui
     * @paramCommonPidVo
     * @return
     */
    @PostMapping(XFPayUrl.URL_getUserCard)
    public Object getUserCard(@RequestBody CommonPidVo commonPidVo){
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        Result result =  payConfigClientService.GetCardInfoByPid(yoCiUser.getComId(),commonPidVo.getPId());
        if(result.getData()!=null){
            return result;
        }
        Map<String,Object> resMap =new HashMap<>();
        resMap.put("code",200);
        resMap.put("msg","succ");
        resMap.put("data",null);

        Map<String,Long> feeMap =new HashMap<>();
        feeMap.put("costFee",0l);
        feeMap.put("deposit",0l);

        resMap.put("fee",feeMap);

        Result result1 = payConfigClientService.GetXFAccount(commonPidVo.getComId(),commonPidVo.getPId().intValue(),0);
        if(result1.getData()!=null){
            EntityXfAccountInfo entityXfAccountInfo = JSON.parseObject(JSON.toJSONString(result1.getData()),EntityXfAccountInfo.class);
            Result result2  = payConfigClientService.GetXFAccountType(commonPidVo.getComId());
            if(result2.getData()!=null){
                List<EntityXfAccountType> entityXfAccountTypeList = JSON.parseArray(JSON.toJSONString(result2.getData()),EntityXfAccountType.class);
                for (EntityXfAccountType entityXfAccountType :entityXfAccountTypeList){
                    if(entityXfAccountInfo.getAccTypeId().equals(entityXfAccountType.getAccTypeId())){
                        if(entityXfAccountType.getCostFee()!=null) feeMap.put("costFee",entityXfAccountType.getCostFee());
                        if(entityXfAccountType.getDeposit()!=null) feeMap.put("deposit",entityXfAccountType.getDeposit());
                        resMap.put("fee",feeMap);
                        break;
                    }
                }
            }
        }
        return  resMap;
    }



    /**
     * 导入人员（StudentPage/import）
     * */
    @PostMapping(WebApiServiceUrl.URL_ConsumeAccountImportCard)
    public Result StudentPageImport( Long comId,@RequestPart("file") MultipartFile file){
        try {
            YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
            comId = yoCiUser.getComId();
        }catch (Exception e){

        }
        Long timestamp = System.currentTimeMillis();
        //        1、用HSSFWorkbook打开或者创建“Excel文件对象”
        //        2、用HSSFWorkbook对象返回或者创建Sheet对象
        //        3、用Sheet对象返回行对象，用行对象得到Cell对象
        //        4、对Cell对象读写。
        //获得文件名
        Workbook workbook = null ;
        String fileName = file.getOriginalFilename();
        assert fileName != null;
        if(fileName.endsWith("xls")){
            //2003
            try {
                workbook = new HSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else if(fileName.endsWith("xlsx")){
            //2007
            try {
                workbook = new XSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }else{
            try {
                throw new Exception("文件不是Excel文件");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        assert workbook != null;
        Sheet sheet = workbook.getSheetAt(0);
        int rows = sheet.getLastRowNum();// 指的行数，一共有多少行+
        if(rows==0){
            try {
                throw new Exception("请填写数据");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Map<String,Object> map1=new HashMap<>();
        map1.put("key","ImportErr:detail:"+comId+":"+timestamp);
        map1.put("type",1);
        map1.put("name","卡号批量导入");
        map1.put("timestamp",timestamp);
        map1.put("datetime", DateUtil.getDateTime());
        redisUtil.leftPush("ImportErr:"+comId,map1,86400l);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定义日期格式模式
        for (int i = 1; i < rows+1; i++) {

            String errMsg = "";
            // 读取左端单元格
            Row row = sheet.getRow(i);
            // 行不为空
            if (row != null) {

                // **读取cell**
                ImportCardVo importCardVo=new ImportCardVo();

                importCardVo.setTimestamp(timestamp);
                importCardVo.setComId(comId);

                //姓名
                String name = JSON.toJSONString(getCellValue(row.getCell(0))).replace("\"", "").replace("\\t", "");
                if (!CommonUtil.isNull(name) && !name.equals("null")){
                    importCardVo.setPName(name);
                }

                // 人员编号
                String pCode = JSON.toJSONString(getCellValue(row.getCell(1))).replace("\"", "").replace("\\t", "");
                if (!CommonUtil.isNull(pCode) && !pCode.equals("null")){
                    importCardVo.setPCode(pCode);
                }else{
                    errMsg += "编号为空,";
                }

                // 人员卡号
                String cardNo = JSON.toJSONString(getCellValue(row.getCell(2))).replace("\"", "").replace("\\t", "");
                if (!CommonUtil.isNull(cardNo) && !cardNo.equals("null")){
                    importCardVo.setCardNo(cardNo);
                }else{
                    errMsg += "卡号为空,";
                }

                //卡有效期
                String endDate = JSON.toJSONString(getCellValue(row.getCell(3))).replace("\"", "").replace("\\t", "");
                if (!CommonUtil.isNull(endDate) && !endDate.equals("null")) {
                    endDate = sdf.format(new Date(Long.parseLong(endDate)));
                    importCardVo.setEndDate(endDate);
                } else {
                    importCardVo.setEndDate("2099-01-01 00:00:00");
                }

                //调用mq
                if(CommonUtil.isNull(errMsg)){
                    mqSimpleService.importCard(importCardVo);
                }else{
                    Map<String,Object> map=new HashMap<>();
                    map.put("errMsg",errMsg);
                    map.put("json",importCardVo);
                    redisUtil.leftPush("ImportErr:detail:"+comId+":"+timestamp,map,86400l);
                }
            }
        }
        return ResultUtil.success();
    }



    /**
     * 个人账户挂失/解挂（ConsumeAccount/cardLoss）
     * */
    @PostMapping(WebApiServiceUrl.URL_ForceDelCard)
    public Result ForceDelCard(@RequestBody WebDelCardVo webDelCardVo){
        log.info("个人强制删除卡请求参数:{{}}",webDelCardVo);
        Result result = payConfigClientService.getCardInfoByCardNo(SecurityUtils.getYoCiUser().getComId(),webDelCardVo.getCardNo());
        if(result.getCode()!=200){
            return result;
        }

        EntityCardInfo entityCardInfo  = JSON.parseObject(JSON.toJSONString(result.getData()), EntityCardInfo.class);

        /**
         * accountNo: "1P2537"
         * cardNo: "87345"
         * cardState: 2
         * comId: 1
         * pId: 2537
         */
        Map<String,Object> map =new HashMap<>();
        map.put("accountNo", entityCardInfo.getAccountNo());
        map.put("cardNo", webDelCardVo.getCardNo());
        map.put("comId", webDelCardVo.getComId());
        map.put("pId", entityCardInfo.getPId());
        map.put("user", SecurityUtils.getUsername());
//        map.put("user", "admin1");
        map.put("cardState", 2);
        return payConfigClientService.UpdatecardState(map);

//        return consumeAccountService.ConsumeAccountCardLoss(map);
    }


    /**
     * 充值中列表 -按退款订单号
     */
    @PostMapping(WebApiServiceUrl.URL_gzhRefunding)
    public Result gzhRefunding(@RequestBody GzhRefundQueryRequest request){
        YoCiUser yoCiUser= SecurityUtils.getYoCiUser();
        request.setComId(yoCiUser.getComId());
        if(yoCiUser.getRole()>22l){
            return ResultUtil.error(ResultEnum.Err_4);
        }
        request.setPayState(-1);
        request.setConsState(11);
        return payConfigClientService.gzhRefunding(request);
    }

    /**
     * 充值中列表 -处理退款中
     */
    @PostMapping(WebApiServiceUrl.URL_gzhRefundMng)
    public Result gzhRefundMng(@RequestBody GzhMngHandleRequest request){
        YoCiUser yoCiUser= SecurityUtils.getYoCiUser();
        request.setComId(yoCiUser.getComId());
        if(yoCiUser.getRole()>22l){
            return ResultUtil.error(ResultEnum.Err_4);
        }
        return payHandleFeignService.gzhRechageRefundMng(request);
    }



}
